﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Timers;
using AllInOne.Models;
using AllInOne.ViewModels;
using AllInOne.MainPage;
using System.Threading;
using System.Runtime.InteropServices;
using AllInOne.Entity;
using AllInOne.Classes;
using static System.Net.Mime.MediaTypeNames;

namespace AllInOne.MainPages
{
    /// <summary>
    /// ReadCardTipsPage.xaml 的交互逻辑
    /// </summary>
    public partial class ReadCardTips_Page : Page
    {

        #region 第一部分--身份证阅读器dll
        //二代证相关API---------------------------------------------------------
        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_GetCOMBaud(int iPort, ref uint puiBaudRate);

        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_SetCOMBaud(int iPort, uint uiCurrBaud, uint uiSetBaud);

        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_StartFindIDCard(int iPort, byte[] pucManaInfo, int iIfOpen);

        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_SelectIDCard(int iPort, byte[] pucManaMsg, int iIfOpen);

        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_ReadBaseMsg(int iPort, byte[] pucCHMsg, ref uint puiCHMsgLen, byte[] pucPHMsg, ref uint puiPHMsgLen, int iIfOpen);

        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_ReadBaseFPMsg(int iPort, byte[] pucCHMsg, ref uint puiCHMsgLen, byte[] pucPHMsg, ref uint puiPHMsgLen, byte[] pucFPMsg, ref uint puiFPMsgLen, int iIfOpen);

        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_GetSAMIDToStr(int iPort, StringBuilder pcSAMID, int iIfOpen);

        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_ReadNewAppMsg(int iPort, byte[] pucAppMsg, ref uint puiAppMsgLen, int iIfOpen);

        #endregion

        #region 第二部分--页面部分

        private MainWindow parent;

        private System.Timers.Timer tipsTimer;


        public string cardtype;

        public ReadCardTips_Page()
        {
            InitializeComponent();
            testName.Text = "杨智可";
            testID.Text = "410";
            testAddress.Text = "河南";
        }

        public ReadCardTips_Page(MainWindow parent)
        {
            InitializeComponent();
            this.parent = parent;
            this.InitTimer();
        }


        private void BtnBackToIndex_MouseUp(object sender, MouseButtonEventArgs e)
        {
            StopCountDown();
            this.parent.ResetIndex();
        }


        /// <summary>
        /// 初始化读身份证信息
        /// </summary>
        public void InitPage(string _cardtype)
        {
            //制卡类型
            cardtype =_cardtype;
            InitTipCurrent();
            //this.imgTitle.Source = new BitmapImage(new Uri(this.parent.enterBusinessInfo.getImgTitleUrl()));
        }

        //AuthViewModel viewModel = new AuthViewModel() { IDCardMsg = "身份证读卡器未连接！", CountDown = Classes.SystemParam.CountDownAuth };
        IDPeapleViewModel viewModel;

        ////定时退出
        //Task countTask;
        ////定时退出
        //Task task;

        bool startFlag = true;
        //readonly CancellationTokenSource tokenSource = new CancellationTokenSource();
        CancellationTokenSource tokenSource;
        internal string strID;
        internal string strName;
        internal string strAddress;
        bool readFlag = false;

        CancellationToken token;
        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            //判断是否显示测试区域
            if (SystemParam.TestPage == 1)
            {
                spTest.Visibility = Visibility.Visible;

                testName.Text = "杨智可";
                testID.Text = "410325199205280511";
                testAddress.Text = "河南嵩县";
            }
            else
            {
                spTest.Visibility = Visibility.Hidden;
            }
            //01开启身份证识别倒计时60秒
            viewModel = new IDPeapleViewModel() { IDCardMsg = "", CountDown = Classes.SystemParam.CountDownAuth };
            DataContext = viewModel;
            //this.parent.ShowText("1进入页面：" + System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            //显示倒计时
            Cpb.Maximum = viewModel.CountDown;
            tokenSource = null;
            tokenSource = new CancellationTokenSource();
            token = tokenSource.Token;
            Task countTask = new Task(() =>
            {
                //判断是否取消任务
                while (!token.IsCancellationRequested)
                {
                    viewModel.CountDown--;
                    if (viewModel.CountDown <= 0)
                        QuitView(false);
                    Thread.Sleep(1000);
                }
            }, token);
            countTask.Start();
            //开始读取身份证号
            Task task = new Task(async () =>
            {
                while (startFlag)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    ReadIDCard();
                    await Task.Delay(1000);
                }
            }, token);
            task.Start();
        }

        /// <summary>
        /// 读取身份证信息
        /// </summary>
        private void ReadIDCard()
        {
            int iIfOpen = 1;//自动打开设备标志。如果设置为1，则在接口内部自动实现打开设备和关闭设备，无需调用者再添加。

            StringBuilder strSAMID = new StringBuilder(64 + 1);

            byte[] byCHMsg = new byte[256 + 1];        //个人基本信息
            uint uiCHMsgSize = 0;                       //个人基本信息字节数
            byte[] byPHMsg = new byte[1024 + 1];       //照片信息
            uint uiPHMsgSize = 0;                       //照片信息字节数
            byte[] byFgnCardSign = new byte[2];       //证件类型标识

            int iPort = 1001;
            int iResult;
            SimpleConsole.WriteError("1读取身份证开始：",null);

            try
            {
                iResult = SDT_GetSAMIDToStr(iPort, strSAMID, iIfOpen);
                SimpleConsole.WriteError("4读取身份证开始：", null);
                if (0x90 != iResult)
                {
                    SimpleConsole.WriteError(String.Format("获取SAMID号失败，错误代码：{0:D}", iResult), null);
                    viewModel.IDCardMsg = "身份证读卡器未连接！" + String.Format("获取SAMID号失败，错误代码：{0:D}", iResult);
                }
                else
                {
                    this.parent.ShowText("身份证读卡器已连接！");
                    viewModel.IDCardMsg = "身份证读卡器已连接！";
                    byte[] byManaID = new byte[8];
                    //寻卡
                    iResult = SDT_StartFindIDCard(iPort, byManaID, iIfOpen);
                    byManaID.Initialize();
                    iResult = SDT_SelectIDCard(iPort, byManaID, iIfOpen);
                    SimpleConsole.WriteError("5读取身份证开始：", null);
                    if (0x90 == iResult)
                    {
                        iResult = SDT_ReadBaseMsg(iPort, byCHMsg, ref uiCHMsgSize, byPHMsg, ref uiPHMsgSize, iIfOpen);
                        if (0x90 == iResult)
                        {
                            //AuthType = 1;
                            //截断数据获得证件类型标识
                            SimpleConsole.WriteError("6读取身份证开始：", null);
                            Array.Copy(byCHMsg, 248, byFgnCardSign, 0, 2);
                            if ((byFgnCardSign[0] == 0x49) && (byFgnCardSign[1] == 0x00))
                            {
                                byte[] byFgnCardNo = new byte[30];      //Card No
                                Array.Copy(byCHMsg, 122, byFgnCardNo, 0, 30);
                                strID = Encoding.Unicode.GetString(byFgnCardNo).Trim();
                            }
                            else if ((byFgnCardSign[0] == 0x4A) && (byFgnCardSign[1] == 0x00))//大写字母'I'（0x4A 0x00）表示为港澳台居住证
                            {
                                byte[] byID = new byte[36];
                                Array.Copy(byCHMsg, 122, byID, 0, 36);
                                strID = Encoding.Unicode.GetString(byID).Trim();

                                //读取姓名：
                                byte[] byName = new byte[30];
                                Array.Copy(byCHMsg, 0, byName, 0, 30);
                                strName = Encoding.Unicode.GetString(byName).Trim();

                                //读取住址：
                                byte[] byAddress = new byte[70];
                                Array.Copy(byCHMsg, 52, byAddress, 0, 70);
                                strAddress = Encoding.Unicode.GetString(byAddress).Trim();
                            }
                            else
                            {
                                byte[] byID = new byte[36];
                                Array.Copy(byCHMsg, 122, byID, 0, 36);
                                strID = Encoding.Unicode.GetString(byID).Trim();

                                //读取姓名：
                                byte[] byName = new byte[30];
                                Array.Copy(byCHMsg, 0, byName, 0, 30);
                                strName = Encoding.Unicode.GetString(byName).Trim();

                                //读取住址：
                                byte[] byAddress = new byte[70];
                                Array.Copy(byCHMsg, 52, byAddress, 0, 70);
                                strAddress = Encoding.Unicode.GetString(byAddress).Trim();
                            }

                            //向外传递数据
                            //Log.Info($"身份证号：{strID}");
                            //Log.Info($"姓名：{strName}");
                            //string str = "";
                            //for (int i = 0; i < byCHMsg.Length; i++)
                            //{
                            //    str += " " + byCHMsg[i].ToString("X2");
                            //}
                            //Log.Info($"身份数据：{str}");
                            SimpleConsole.WriteError("7读取身份证开始：", null);
                            viewModel.Name = strName;
                            viewModel.IDCard = strID;
                            viewModel.Address = strAddress;
                            SimpleConsole.WriteError("3得到身份证信息" + strID + strName + strAddress, null);
                            QuitView(true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                SimpleConsole.WriteError("2读取身份证开始：" + ex.ToString(), null);
                Log.Error(nameof(ReadIDCard), ex);
            }
        }


        //01开启身份证识别倒计时60秒
        public void StopCountDown()
        {
            this.Dispatcher.Invoke(new Action(() =>
            {
                if (tokenSource != null)
                {
                    tokenSource.Cancel();
                }
            }));
        }

        private void QuitView(bool result)
        {
            this.Dispatcher.Invoke(new Action(() =>
            {
                SimpleConsole.WriteError("读取身份证开始：", null);
                //显示数字的线程关闭
                if (tokenSource != null)
                {
                    tokenSource.Cancel();
                }
                //显示动画的定时器也关闭
                StopTimer();
                readFlag = result;
                //跳转页面
                SkipPage();
            }));
        }
        #endregion



        #region 第三部分--显示放置身份证动画
        private int photoIndex = 0;
        private int interval = 2;
        private int stay = 5;

        /// <summary>
        /// 定时器--显示放置身份证动画
        /// </summary>
        public void InitTimer()
        {
            this.tipsTimer = new System.Timers.Timer();
            this.tipsTimer.Interval = 100;
            this.tipsTimer.Elapsed += new ElapsedEventHandler(delegate (object sender, ElapsedEventArgs e)
            {

                photoIndex++;
                int step = 1;
                if (photoIndex > 0 && photoIndex < 4 * interval)
                {
                    step = photoIndex / interval + 1;
                }
                else
                {
                    step = 5;
                    if (photoIndex > stay + 4 * interval)
                    {
                        photoIndex = 0;
                    }
                }

                this.Dispatcher.Invoke(new Action(delegate ()
                {
                    this.imgTips.Source = new BitmapImage(new Uri(string.Format("pack://application:,,,/images/put_id{0}.png", step)));
                }));


            });
            this.tipsTimer.Enabled = false;
        }

        public void StartTimer()
        {
            this.tipsTimer.Enabled = true;

            this.photoIndex = 0;
            Console.WriteLine("播放声音：请将您的居民二代身份证放置在感应区域。");
            
            this.parent.PlaySound(Properties.Resources.male_put_id, Properties.Resources.female_put_id);
        }


        public void StopTimer()
        {
            this.tipsTimer.Enabled = false;
        }
        
        /// <summary>
        /// 测试按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Test_Btn1_Click(object sender, RoutedEventArgs e)
        {
            //01停止读卡--身份证阅读关闭
            StopCountDown();
            //02展示录入信息页面--将司机信息也带过去
            strName = testName.Text.Trim().Replace(" ","");
            strID = testID.Text.Trim().Replace(" ", "");
            strAddress = testAddress.Text.Trim().Replace(" ", "");
            if (this.parent.DriverInfo == null)
            {
                this.parent.DriverInfo = new DriverInfo();
            }
            this.parent.DriverInfo.xm = strName;//姓名
            this.parent.DriverInfo.sfzmhm = strID;//身份证明号码
            this.parent.DriverInfo.zz = strAddress;//住址

            switch (cardtype)//卡类型
            {
                case "RCZK":
                    this.parent.DriverInfo.cardType = 1;
                    this.parent.Choose_Business(EnterBusinessType.XXLR);
                    break;
                case "CCZK":
                    this.parent.DriverInfo.cardType = 2;
                    this.parent.Choose_Business(EnterBusinessType.CCXXLR);
                    break;
                case "CNLZZK":
                    this.parent.DriverInfo.cardType = 3;
                    this.parent.Choose_Business(EnterBusinessType.CNLZXXLR);
                    break;
                case "YJTZK"://阴极铜制卡
                    this.parent.DriverInfo.cardType = 2;
                    this.parent.Choose_Business(EnterBusinessType.YJTXXLR);
                    break;
                default:
                    this.parent.DriverInfo.cardType = 0;
                    break;
            }
            
        }
        #endregion

        /// <summary>
        /// 判断是退出还是进入下一步人员信息
        /// </summary>
        /// <param name="result"></param>
        private void SkipPage()
        {
            if (readFlag)//true 表示身份证阅读器读到了数据
            {
                //跳到下一页
                if (this.parent.DriverInfo == null)
                {
                    this.parent.DriverInfo = new DriverInfo();
                }
                this.parent.DriverInfo.xm = strName;//姓名
                this.parent.DriverInfo.sfzmhm = strID;//身份证明号码
                this.parent.DriverInfo.zz = strAddress;//住址
                switch (cardtype)//卡类型
                {
                    case "RCZK":
                        this.parent.DriverInfo.cardType = 1;
                        this.parent.Choose_Business(EnterBusinessType.XXLR);
                        break;
                    case "CCZK":
                        this.parent.DriverInfo.cardType = 2;
                        this.parent.Choose_Business(EnterBusinessType.CCXXLR);
                        break;
                    case "CNLZZK":
                        this.parent.DriverInfo.cardType = 3;
                        this.parent.Choose_Business(EnterBusinessType.CNLZXXLR);
                        break;
                    case "YJTZK"://阴极铜制卡
                        this.parent.DriverInfo.cardType = 2;
                        this.parent.Choose_Business(EnterBusinessType.YJTXXLR);
                        break;
                    default:
                        this.parent.DriverInfo.cardType = 0;
                        this.parent.Choose_Business(EnterBusinessType.XXLR);
                        break;
                }
                
            }
            else
            {   //false 表示超时的情况
                //回到首页
                //MessageBox.Show("刷身份证超时退出到前一页面");
                //展示另外主要菜单
                this.parent.ShowJszIndex();
            }
        }

        #region 第四部分--手动测试

        private void Test_Btn2_Click(object sender, RoutedEventArgs e)
        {
            //string str = "杨智";
            //Log.Info($"测试数据：{str}");
            ////QuitView(false);
            Log.Info("测试数据杨3");
        }
        #endregion


        /// <summary>
        /// 初始化当前所在页面提示
        /// </summary>
        /// <param name="result"></param>
        private void InitTipCurrent()
        {
            try
            {
                this.Dispatcher.Invoke(new Action(delegate ()
                {
                    switch (cardtype)//卡类型
                    {
                        case "RCZK":
                            txtIdentfy.Text = " 制卡页面 > 入厂货物 > 身份识别";
                            break;
                        case "CCZK":
                            txtIdentfy.Text = " 制卡页面 > 出厂货物 > 身份识别";
                            break;
                        case "CNLZZK":
                            txtIdentfy.Text = " 制卡页面 > 厂内流转货物 > 身份识别";
                            break;
                        case "YJTZK"://阴极铜制卡
                            txtIdentfy.Text = " 制卡页面 > 阴极铜制卡 > 身份识别";
                            break;
                        default:
                            txtIdentfy.Text = " 制卡页面 > 货物类型 > 身份识别";
                            break;
                    }
                }));
            }
            catch (Exception ex)
            {
                Log.Info("身份识别：" + ex.ToString());
            }
        }

    }
}